package com.mlx.meng.aop;

import com.mlx.meng.annotation.DataPermissionColumn;
import com.mlx.meng.author.AbstractDataPermissionColumnAuthorization;
import com.mlx.meng.verify.DataPermissionColumnVerification;
import com.mlx.meng.tool.DataPermissionException;
import com.mlx.meng.tool.DataPermissionUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;


@Aspect
@Order(10000)
public class DataPermissionColumnAOP {

    @Autowired(required = false)
    private AbstractDataPermissionColumnAuthorization<?> authorization;

    @Pointcut(value = "@annotation(com.mlx.meng.annotation.DataPermissionColumn)")
    public void dataFilterPointcut(){
    }

    private DataPermissionColumn getDataAuthorAnnotation(JoinPoint joinPoint){
        MethodSignature signature =(MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        return method.getDeclaredAnnotation(DataPermissionColumn.class);
    }

    @AfterReturning(value = "dataFilterPointcut()", returning = "dataList")
    public void dataFilter(JoinPoint joinPoint, Object dataList) throws Exception{

        long startTime = System.currentTimeMillis();
        if (dataList == null){
            return;
        }
        if (!(dataList instanceof Collection)){
            return;
        }
        if (((Collection<?>) dataList).isEmpty()){
            return;
        }

        // 获取数据授权注解
        DataPermissionColumn columnPermission = getDataAuthorAnnotation(joinPoint);
        // 获取表名
        String tableName = columnPermission.tableName();

        String[] foreignKeys = columnPermission.foreignKeys();

        boolean disEnable = columnPermission.disEnable();

        String setMethodName = columnPermission.setMethodName();

        String getAllFieldMethodName = columnPermission.getAllFieldMethodName();

        Class<?> fieldType = columnPermission.fieldType();

        Class<?> valueType = columnPermission.valueType();

        int fieldTypeIndex = columnPermission.fieldTypeIndex() % 2;

        if (disEnable){
            return;
        }

        if (DataPermissionUtil.isNotEmpty(setMethodName) && DataPermissionUtil.isEmpty(getAllFieldMethodName)){
            throw new DataPermissionException("ColumnPermission注解错误：setMethodName属性不空，getAllFieldMethodName属性不可以空");
        }


        // 如果getMethodName为空，根据权限字段名称获取对应属性的属性值进行权限判断；
        // 否则获取getMethodName指定的方法，通过权限字段名称为方法参数获取对应权限字段的值进行权限判断
        if (DataPermissionUtil.isEmpty(setMethodName)){
            authorization.dataFilter((Collection<?>) dataList, tableName, foreignKeys);
        }else {
            authorization.dataFilter((Collection<?>) dataList, tableName, foreignKeys, setMethodName, fieldType, valueType, fieldTypeIndex, getAllFieldMethodName);
        }

        long endTime = System.currentTimeMillis();

        System.out.printf("列数据权限过滤执行时间：【%d】ms%n", endTime - startTime);
    }



//    @AfterReturning(value = "dataFilterPointcut()", returning = "dataList")
//    public void dataFilter(JoinPoint joinPoint, Object dataList) throws Exception{
//
//        long startTime = System.currentTimeMillis();
//        if (dataList == null){
//            return;
//        }
//        if (!(dataList instanceof Collection)){
//            return;
//        }
//        if (((Collection<?>) dataList).isEmpty()){
//            return;
//        }
//
//        // 获取数据授权注解
//        DataPermissionColumn columnPermission = getDataAuthorAnnotation(joinPoint);
//        // 获取表名
//        String tableName = columnPermission.tableName();
//
//        String[] foreignKeys = columnPermission.foreignKeys();
//
//        boolean disEnable = columnPermission.disEnable();
//
//        String setMethodName = columnPermission.setMethodName();
//
//        String getAllFieldMethodName = columnPermission.getAllFieldMethodName();
//
//        Class<?> fieldType = columnPermission.fieldType();
//
//        Class<?> valueType = columnPermission.valueType();
//
//        int fieldTypeIndex = columnPermission.fieldTypeIndex() % 2;
//
//        if (disEnable){
//            return;
//        }
//
//        if (DataPermissionUtil.isNotEmpty(setMethodName) && DataPermissionUtil.isEmpty(getAllFieldMethodName)){
//            throw new DataPermissionException("ColumnPermission注解错误：setMethodName属性不空，getAllFieldMethodName属性不可以空");
//        }
//
//
//        // 通过表名获取本表伪列数据权限
//        DataPermissionColumnVerification tablePermission = authorization.getTableColumnPermissions();
//
//        DataPermissionColumnVerification.DataPermissionColumnEntityVerification entityVerification = tablePermission.buildDataPermissionColumnEntity(tableName, foreignKeys);
//
//        // 没有数据权限就没有数据
//        if (entityVerification.isNotExistDataPermission()){
//            ((Collection<?>) dataList).clear();
//            return;
//        }
//
//        // 获取数据类型
//        Iterator<?> iterator1 = ((Collection<?>) dataList).iterator();
//        Object next = iterator1.next();
//        Class<?> aClass = next.getClass();
//
//        // 生成迭代器
//        Iterator<?> iterator = ((Collection<?>) dataList).iterator();
//
//        // 如果getMethodName为空，根据权限字段名称获取对应属性的属性值进行权限判断；
//        // 否则获取getMethodName指定的方法，通过权限字段名称为方法参数获取对应权限字段的值进行权限判断
//        if (DataPermissionUtil.isEmpty(setMethodName)){
//            // 获取数据类型的属性集合
//            Map<String, Field> fieldMap = DataPermissionUtil.gainClassField(aClass);
//            // 获取所有的权限字段
//            Set<String> permissionField = entityVerification.getEntityColumnPermission();
//            // 检查数据类型是否拥有对应权限字段的属性
//            for (String k : permissionField){
//                if (!(fieldMap.containsKey(k))){
//                    throw new DataPermissionException("返回数据的数据类型不存在权限字段【%s】指定的属性", k);
//                }
//            }
//            // 行数据权限过滤
//            while (iterator.hasNext()){
//                // 获取集合中的元素
//                Object data = iterator.next();
//                // 通过集合中的元素与属性集合判断是否拥有对应数据权限
//                entityVerification.columnPermissionFilter(data, fieldMap);
//            }
//        }else {
//            // 获取setMethodName指定的属性值获取方法
//            Method setMethod = null;
//            if (fieldTypeIndex == 0){
//                setMethod = aClass.getDeclaredMethod(setMethodName, fieldType, valueType);
//            }else {
//                setMethod = aClass.getDeclaredMethod(setMethodName, valueType, fieldType);
//            }
//
//            Method getAllFieldMethod = aClass.getDeclaredMethod(getAllFieldMethodName);
//
//            Class<?> returnType = getAllFieldMethod.getReturnType();
//
//            if (!(Collection.class.isAssignableFrom(returnType))){
//                throw new DataPermissionException("getAllFieldMethodName方法返回类型不是Collection类型");
//            }
//
//            // 行数据权限过滤
//            while (iterator.hasNext()){
//                // 获取集合中的元素
//                Object data = iterator.next();
//                // 通过集合中的元素与与属性值获取方法判断是否拥有对应数据权限
//                entityVerification.columnPermissionFilter(data, setMethod, fieldTypeIndex, getAllFieldMethod);
//            }
//        }
//
//        long endTime = System.currentTimeMillis();
//
//        System.out.printf("列数据权限过滤执行时间：【%d】ms%n", endTime - startTime);
//    }

}
